/**
 * Promise的类型系统
 * + 泛型: Promise 类型使用泛型来定义异步操作成功时返回的值的类型。
 * + 类型推断: TypeScript 能够根据 Promise 的泛型参数推断出 then 和 catch 方法中的参数类型。
 * + 错误处理: 使用 catch 方法处理 Promise 的错误时，TypeScript 知道错误是 Error 类型。
 */

// 定义类型：Promise<string> 缺陷：只对 resolve 的返回值起约束, reject 通常传递一个 Error 对象
// 1. 指定返回值
function fetchData(): Promise<string> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      let flag = false
      if (flag) {
        resolve('success')
      } else {
        reject(new Error('failure'))
      }
    }, 1000)
  })
}

fetchData().then((res) => {
  console.log(res);  // TypeScript 能推断出 res 的类型为 string
}).catch((res) => {
  console.log(res);
})

// 2.处理多个 Promise - Promise.all()
function fetchUser(): Promise<string> {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('user')
    }, 1000)
  })
}

function fetchOthers(): Promise<number[]> {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve([1, 1, 2, 3, 5, 8, 13, 21])
    }, 1000)
  })
}

Promise.all([fetchUser(), fetchOthers()])
  .then(([user, others]) => {
    console.log(`用户：${user}, 订单：${others}`);
  })

// 3. 处理 Promise 错误
function riskyOperation(): Promise<number> {
  return new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('出错了')), 1000);
  });
}

riskyOperation()
  .then(result => {
    console.log(result);
  })
  .catch(error => {
    console.error(error.message); // TypeScript 知道 `error` 是 `Error` 对象
  });

// 4. 自定义 Promise 类型
interface User {
  id: number;
  name: string;
}

function getUserById(userId: number): Promise<User> {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ id: userId, name: 'John Doe' });
    }, 1000);
  });
}

getUserById(1).then(user => {
  console.log(`用户ID: ${user.id}, 用户名: ${user.name}`);
});



